/**
 * This class is an session bean class
 * that performes all the oprations for 
 * the project entity.
 * It implements the IPerformeProjects interface
 */
package com.teamreinforce.ejb.model;

import com.teamreinforce.ejb.beans.EtapeFacade;
import com.teamreinforce.ejb.beans.NotificationFacade;
import com.teamreinforce.ejb.entities.Collaborateur;
import com.teamreinforce.ejb.entities.Etape;
import com.teamreinforce.ejb.entities.Notification;
import com.teamreinforce.ejb.entities.Projet;
import com.teamreinforce.ejb.entities.Risque;
import com.teamreinforce.ejb.entities.Role;
import com.teamreinforce.ejb.entities.Tache;
import com.teamreinforce.utils.TeamReinforceTimeUtils;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

/**
 *
 * @author tidiane
 */
@Stateless
public class PerformeProjects implements IPerformeProjects{
    
    // Entity manager injection
    @PersistenceContext(unitName="TeamreinforceEJBPU")
    private EntityManager em;

    @EJB
    private NotificationFacade notificationF;
    
    @EJB
    private EtapeFacade etapeF;
    
    @Override
    public Projet getProject(String titre) {
        TypedQuery<Projet> query = em.createNamedQuery("Projet.findByTitre", Projet.class);
        query.setParameter("titre", titre);
        return query.getSingleResult();
    }
    @Override
    public void addCollaboratorToProject(Projet project, Collaborateur collaborator, String roleName) {
        // Adding collaborator
        Role _role = new Role(Integer.SIZE, roleName);
        _role.setProjet(project);
        _role.setCollaborateur(collaborator);
        em.persist(_role);
        
        // Make motification for the collaborator
        notificate(collaborator, "Vous avec été ajouté au projet " + project.getTitre().toUpperCase() + " comme " + roleName.toUpperCase());
    }

    @Override
    public void removeCollaboratorFromProject(Projet project, Collaborateur collaborator) {
        // Seek for the role and remove it
        for ( Role r : project.getRoleList()){
            if ( r.getCollaborateur().equals(collaborator))
                em.remove(r);
        }
        
        // Make notification
        notificate(collaborator, "Vous avec été enlévé du projet " + project.getTitre().toUpperCase());
    }

    @Override
    public void updateCollaboratorRole(Projet project, Collaborateur collaborator, String newRoleName) {
        // Seek for the role and update its name
        for (Role r : project.getRoleList()){
            if (r.getCollaborateur().equals(collaborator))
                r.setRole(newRoleName);
        }
        
        // Make notification
        notificate(collaborator, "Vous êtes maintenant "+ newRoleName.toUpperCase() + " dans le projet " + project.getTitre().toUpperCase());
    } 
    
    /**
     * Add the new notification
     * of the given collaboratorme parametre une tache et colla
     * @param collaborator
     * @param notificationMessage 
     */
    public void notificate(Collaborateur collaborator, String notification){
        List<Notification> lnf = notificationF.findAll();
        Notification nf;
        int nid = 1;
        if (lnf.size() > 0){
            nf = lnf.get(lnf.size() - 1);
            nid = nf.getIdNotification() + 1;
        }
         
        System.out.println(" NIDDD == " + nid);
        Notification _notification = new Notification();
        _notification.setDateHeureNotifications(TeamReinforceTimeUtils.DATE + " à " + TeamReinforceTimeUtils.TIME);
        _notification.setNotification(notification);
        Query query = em.createNativeQuery("INSERT INTO notification VALUES (" + nid + ", '" + _notification.getDateHeureNotifications() + "', '" + _notification.getNotification() + "', " + collaborator.getIdCollaborateur() + ")");
        query.executeUpdate();
    }

    @Override
    public void assignTaskToCollaborator(Collaborateur collaborator, Tache task) {
        
        Query query = em.createNativeQuery("INSERT INTO realise VALUES (" + collaborator.getIdCollaborateur() + "," + task.getIdTache() + ")");
        
        int result = query.executeUpdate();
        
        Projet _project = task.getEtape().getProjet();
        String project = _project.getTitre().toUpperCase();
        
        // notification ...
        notificate(collaborator, "Vous êtes assigné à la tâche " + task.getLibelle().toString() + " pour le projet " + project);
    }

    @Override
    public void removeTaskFromCollaborator(Collaborateur collaborator, Tache task) {
        for ( Tache t : collaborator.getTacheList()){
            if (t.equals(task))
                em.remove(t);
        }
        
        Projet _project = task.getEtape().getProjet();
        String project = _project.getTitre().toUpperCase();
        
        // notification ...
        notificate(collaborator, "Vous n'êtes plus assigné à la tâche " + task.getLibelle().toString() + " pour le projet " + project);
    }

    @Override
    public Projet createProject(String titre, String description, String dateDebut, String dateFin) {
        Projet _project = new Projet(Integer.SIZE, titre, dateDebut, dateFin);
        if ( description != null && !description.isEmpty()) _project.setDescription(description);
        em.persist(_project);
        return _project;
    }

    @Override
    public Etape addStepToProject(Projet project, String libelle, String description, String dateDebut, String dateFin) {
        Etape step = new Etape(Integer.SIZE, libelle, dateDebut, dateFin);
        if (description != null && !description.isEmpty()) step.setDescription(description);
        step.setDuree(TeamReinforceTimeUtils.calculateDuration(dateDebut, dateFin));
        step.setProjet(project);
        em.persist(step);
        em.flush();
        return step;
    } 
  
    @Override
    public Tache addTaskToStep(Etape step, String libelle, String description, String dateDebut, String dateFin) {
        Tache task = new Tache(Integer.SIZE, libelle, dateDebut, dateFin, 0);
        if (description != null && !description.isEmpty()) task.setDescription(description);
        // calculate the duration
        task.setDuree(TeamReinforceTimeUtils.calculateDuration(dateDebut, dateFin));
        step.setDuree(step.getDuree() + task.getDuree());
        task.setEtape(step);
        em.persist(task);
        etapeF.edit(step);
        em.flush();
        return task;
    }

    @Override
    public void updateTaskAdvencement(Tache task, int avencement) {
        task.setAvancement(avencement);
    }

    @Override
    public void addRisqueToProject(Projet project, String risque, int probalilite, String impact, String planB) {
        Risque _risk = new Risque(probalilite, risque, probalilite, impact, planB);
        _risk.setProjet(project);
        em.persist(_risk);
    }

    @Override
    public List<Projet> getAllProjects() {
       return em.createQuery("SELECT p FROM Projet p", Projet.class).getResultList();
    }

    @Override
    public Projet getProjectByTitle(String title) {
        try{
            TypedQuery<Projet> query = em.createNamedQuery("Projet.findByTitre", Projet.class).setParameter("titre", title);
            return query.getSingleResult();
        }catch (Exception e){
            System.out.println(" Error : ICI");
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Projet getProjetById(int pid) {
        TypedQuery<Projet> query = em.createQuery("SELECT p FROM Projet p WHERE p.idProjet = :pid", Projet.class).setParameter("pid", pid);
        return query.getSingleResult();
    }
}